// v2.0
#include "ISBN.h"
#include <string.h>
#include <iostream>
#include <ctype.h>
using namespace std;
//
ISBN::ISBN(){
    strcpy(area,"");
	strcpy(publisher,"");
	strcpy(title,"");
	strcpy(isbn,"");
	strcpy(delimiter,"");
	delimiter[1]='\0';
	reg=vlid=0;
}
//
int ISBN::decode(const ISBNPrefix& list){
    // Thu chon area tu 1 den 5 ki tu
     for (int i=0; i<5;i++){
         area[i]=isbn[i];
         area[i+1]='\0';
         if (list.registered(atol(area))){
                            // Thu chon publicsher tu
                            for (int j=list.minNoDigits(atol(area));j<=7;j++){
                                for (int t=0;t<j;t++)
                                     publisher[t]=isbn[t+strlen(area)];
                                     publisher[j]='\0';
                                if (list.registered(atol(area), publisher)){
                                                   for (int t=0; t<strlen(isbn)-(strlen(area)+strlen(publisher))-1;t++)
                                                   title[t]=isbn[strlen(area)+strlen(publisher)+t];
                                                   title[strlen(isbn)-strlen(area)-strlen(publisher)-1]='\0';
                                                   return 1;
                                }
                            }
         }
     }
     return 0;
};
//
ISBN::ISBN(const ISBN& obj)
{ 
    if (this!=&obj)
    {
	strcpy(isbn,obj.isbn);
	strcpy(area,obj.area);
	strcpy(publisher,obj.publisher);
	strcpy(title,obj.title);
	vlid=obj.vlid;
	reg=obj.reg;
	strcpy(delimiter,obj.delimiter);
    }
}
// 
ISBN::ISBN(const char* str, const ISBNPrefix& list){
    vlid=valid(str);
    if (vlid)
    {
             strcpy(isbn,str);
             reg=decode(list);
             strcpy(delimiter,"-");
	         delimiter[1]='\0';
    }
    else {
         strcpy(area,"");
	     strcpy(publisher,"");
	     strcpy(title,"");
      	 strcpy(isbn,"");
	     strcpy(delimiter,"");
	     delimiter[1]='\0';
         reg=vlid=0;
        }
}
//
void ISBN::style(char c){
     delimiter[0]='-';
     if (c==' '||c=='-'||c=='\0') delimiter[0]=c; 
} 
int ISBN::empty() const{
    return !vlid;
}
int ISBN::registered() const{
    return reg;
} 
void ISBN::toStr(char* str) const{
     strcpy(str,isbn);
}
void ISBN::toStrWithStyle(char* str) const{
     if (reg) 
	{
        strcpy(str,"");
		strcat(str,area);
		strcat(str,delimiter);
		strcat(str,publisher);
		strcat(str,delimiter);
		strcat(str,title);
		strcat(str,delimiter);
		int l=strlen(str);
		str[l]=isbn[strlen(isbn)-1];
		str[l+1]='\0';
	}
	else toStr(str);
}
void ISBN::display(ostream& os) const{
    if (!reg) os<<isbn;
	else {
		char temp[15];
		toStrWithStyle(temp); 
		os<<temp;
	}
}
int ISBN::accept(istream& is, const ISBNPrefix& list){
    do {
    	cout<<"Enter ISBN (0 to quit): ";
    	cin.getline(isbn,12);
    	if (is.fail()) { is.clear(); is.ignore(INT_MAX,'\n');}
    	if (strcmp(isbn,"0")!=0) 
    	{
    		if (valid(isbn)) 
    		{
                vlid=1;
             
    			reg=decode(list);
	    		if (reg) style('-');
		    	if (!reg)
		    	{
			    	cout<<"This ISBN does not have a registered prefix\n";
                    cout<<"Do you still wish to continue (y or n) ? ";
                    char k;
                    is >> k;
                    is.ignore(INT_MAX,'\n');    
	    			if (toupper(k)=='N') {strcmp(isbn,""); vlid=0; return 0;}
    			}
    			return 1;
    		} 
    	} 
    	}
    while(strcmp(isbn,"0")); 
    return 0;    
}
//
    
int operator==(const ISBN& left, const ISBN& right){
    if (strcmp(left.isbn,right.isbn)==0) return 1;
    return 0;
}
//

bool valid(const char* str){
     int error=0;
     // Chuoi rong
     if (strlen(str)==0) {
                         cout << "Empty string. Try again.\n";
                         return 0;
     }
     //Kiem tra ISBN co hop phap ko
     if (strlen(str)!=10) error=1;
     else {
          for (int i=0; i<strlen(str); i++)
          if (isalpha(str[i])) error=2;
          if (error==0) {
                        int sum=0;
                        for (int i=0; i<10;i++)
                        sum+=(str[i]-48)*(10-i);
                        if (sum%11!=0) error=2;
          }
     }
     if (error==1) { cout << " Incorrect number of digits. Try again.\n"; return 0;}
     else if (error==2) {cout << " Invalid check digit. Try again.\n"; return 0;}
     return 1;
}
ostream& operator<<(ostream& os, const ISBN& isbn){
    isbn.display(os);
	return os;
}
